In a distributed system, the data is processed by a set of components connected by a network. The components may have different hardware and/or operating systems and may send and receive data using different transfer syntaxes. Data often needs to be in a form which permits the data to be distributed across the network by converting the data into the format required for the destination component's hardware or operating system.
The Remote Procedure Call (RPC) package defines an industry-standard procedure calling model for distributed applications by invoking an independent set of functions used for accessing remote nodes on a network. The RPC model is derived from the programming model of local procedure calls. An RPC executes a procedure located in a separate address space from the calling code. It uses a procedure declaration for every procedure call. All calls to a procedure must conform to the procedure declaration. The RPC protocols extend the concept of local procedure calls across the network, which means distributed applications may be developed for transparent execution across a network.
The External Data Representation (XDR) defines a standard representation for data in the network to support heterogeneous network computing. The XDR standard data representation convention is a set of library routines that allows a programmer to describe arbitrary data structures in a machine-independent fashion. By using XDR, systems do not have to understand and translate every data format that may exist on the network as there is only the one convention. Data is translated into XDR format before it is sent over the network and, when received, is translated into the data convention used there. New computer architectures can be incorporated into the network without requiring the updating of translation routines.
The current technique for specifying the information exchanged between RPC clients and servers is based on the use of an interface definition file that uses syntax similar to C code. This file contains a specification of each data element that can be exchanged. The type of each such element can be either a primitive (built-in) type, such as integer, character, Boolean, etc., or a complex (derived) type, such as a structure or union. For RPC applications with even modest complexity, the vast majority of exchanged data elements are of a complex type, with most common being structure and union.
To facilitate the development of client and server application software, the RPC/XDR model uses a tool that automatically generates code to translate between the network representation of a data element and the language-specific implementation of that element. Since structure data types are the most relevant for this environment, techniques used for generating translation code for them are the point of focus. A structure is really just an ordered collection of fields, where each field has its own characteristic data type. Consequently, in the RPC/XDR model, the code to translate a structure consists of a sequence of statements, each of which translates one field within the structure. If a field is of a primitive (built-in) data type, there are built-in library routines within the RPC/XDR package that handle the translation, so the code generator creates code that calls into the library. If a field is of a complex type, the code generator creates code that translates it by invoking the auto-generated code for that field's complex type.
The key restriction with the current methodology is that the side that is encoding the data and the side that is decoding it must be using auto-generated code that was derived from exactly the same version of the interface definition. The reason for this is that the encoder simply dumps the encoded version of each successive field into the message stream, and the decoder extracts the exact same number of fields from the message stream at the other side of the connection. If the decoder were to be based on an interface definition for the structure that contained more fields than the encoder knew about, the decoder would try to extract data for the additional fields from the message stream, even though the encoder did not place any such data in the message. On the other hand, if the decoder's structure definition contained fewer fields than the encoder's, the decoder would finish decoding and leave extra data in the message stream. This would interfere with further decoding of structures and other data elements that follow the structure in question, since the decoders for those ensuing elements would try to decode data that is really not part of their elements.
The standard resolution for this problem in the RPC/XDR environment is to simply create new structures, in addition to the old ones, and modify all the relevant elements of the interface definition to ensure that both the old and the new/enhanced structures are used where appropriate. This generally requires the development of an entire new interface definition, and the need for new code to support both the new and the old versions of the interface. Over time, this evolves into a need to support multiple (i.e., even more than two) versions of the interface, which is a serious maintenance issue.
The only real alternative is to use a lock-step migration strategy. When changes are needed to the interface definition, they are made on both the client and the server. All clients and all servers must then be upgraded to the new interface definition in a lock-step deployment. This approach reduces the amount of code required, and thus the maintenance effort, but imposes extreme difficulties in the deployment phase, since incompatible versions of the interface must not coexist.
Therefore, it would be desirable to provide a method and system for communicating between network elements having dissimilar data structure definitions.